package com.xhwl.data.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhwl.common.dto.cent.sdata.RoleDetailDTO;
import com.xhwl.common.enums.config.RoleTypeEnum;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.pojo.cent.sdata.AccountRole;
import com.xhwl.common.pojo.cent.sdata.Project;
import com.xhwl.common.pojo.cent.sdata.Role;
import com.xhwl.common.query.cent.sdata.ProjectQuery;
import com.xhwl.data.dao.IAccountRoleDao;
import com.xhwl.data.service.IAccountRoleService;
import com.xhwl.data.service.IAccountService;
import com.xhwl.data.service.IProjectService;
import com.xhwl.data.service.IRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @description:
 * @author:
 * @create: 2020-11-25
 **/
@Service
public class AccountRoleServiceImpl extends ServiceImpl<IAccountRoleDao, AccountRole> implements IAccountRoleService {
    @Autowired
    IAccountRoleDao accountRoleDao;
    @Autowired
    IRoleService roleService;
    @Autowired
    IAccountService accountService;
    @Autowired
    IProjectService projectService;

    /**
     * 根据角色id分组 挂钩的账号的数量
     *
     * @return
     */
    @Override
    public List<RoleDetailDTO> getCountByRoleId(List<Integer> roleIds) {
        return accountRoleDao.getCountByRoleId(roleIds);
    }

    /**
     * 根据账号id查找所属的所有角色id
     *
     * @param accountId
     * @return
     */
    @Override
    public List<Integer> findRoleIdByAccountId(Integer accountId) {
        QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
        accountRoleQueryWrapper.select("role_id");
        accountRoleQueryWrapper.eq("account_id", accountId);
        List<AccountRole> accountRoleList = accountRoleDao.selectList(accountRoleQueryWrapper);
        List<Integer> roleIdList = accountRoleList.stream().map(e -> e.getRoleId()).collect(Collectors.toList());
        return roleIdList;
    }

    /**
     * 根据角色id查找关联的账号id 列表
     *
     * @param roleIdList
     * @return
     */
    @Override
    public List<Integer> findByRoleId(List<Integer> roleIdList) {
        QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
        accountRoleQueryWrapper.select("account_id");
        if (!CollectionUtils.isEmpty(roleIdList)) {
            accountRoleQueryWrapper.in("role_id", roleIdList);
        }
        List<AccountRole> accountRoleList = this.list(accountRoleQueryWrapper);
        List<Integer> accountIdList = accountRoleList.stream().map(AccountRole::getAccountId).collect(Collectors.toList());
        return accountIdList;
    }


    /**
     * 根据角色类型 查找关联的账号id 列表
     *
     * @param roleTypeEnum
     * @return
     */
    @Override
    public List<Integer> findByRoleType(RoleTypeEnum roleTypeEnum) {
        QueryWrapper<AccountRole> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.select("account_id");
        roleQueryWrapper.eq("type", roleTypeEnum.code);
        List<AccountRole> accountRoleList = accountRoleDao.selectList(roleQueryWrapper);
        List<Integer> accountIdList = accountRoleList.stream().map(e -> e.getAccountId()).collect(Collectors.toList());
        return accountIdList;
    }


    /**
     * 删除 账号角色关联表
     *
     * @param accountIdList
     * @param roleIdList
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAccountRole(List<Integer> accountIdList, List<Integer> roleIdList) {
        try {
            UpdateWrapper<AccountRole> updateWrapper = new UpdateWrapper<>();
            if (!CollectionUtils.isEmpty(roleIdList)) {
                updateWrapper.in("role_id", roleIdList);
            }
            if (!CollectionUtils.isEmpty(accountIdList)) {
                updateWrapper.in("account_id", accountIdList);
            }
            accountRoleDao.delete(updateWrapper);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new BusinessException("删除账号角色关联表失败");
        }

    }

    /**
     * 删除 账号角色关联表
     *
     * @param accountId
     * @param roleIdList
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertAccountRole(Integer accountId, List<Integer> roleIdList) {
        if (CollectionUtils.isEmpty(roleIdList)) {
            return;
        }
        //查询已有角色
        List<Integer> roleIdByAccountId = findRoleIdByAccountId(accountId);
        if (!CollectionUtils.isEmpty(roleIdByAccountId)) {
            //只保留还未添加的角色id
            roleIdList = roleIdList.stream().filter(id -> !roleIdByAccountId.contains(id) && id > 0).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(roleIdList))
            return;
        try {
            List<AccountRole> accountRoles = roleIdList.stream().map(roleId -> {
                AccountRole accountRole = new AccountRole();
                accountRole.setAccountId(accountId);
                accountRole.setRoleId(roleId);
                return accountRole;
            }).collect(Collectors.toList());
            this.saveBatch(accountRoles);
        } catch (Exception e) {
            throw new BusinessException("新增账号角色关联关系失败, "+ e.getMessage());
        }
    }

    @Override
    public ResultJson addVisitorByProjectId(Integer accountId, Integer projectId, Short industryId) {
        List<Role> touristRoleByIndustryId = roleService.getTouristRoleByIndustryId(industryId);
        if (CollectionUtils.isEmpty(touristRoleByIndustryId)) {
            return ResultJson.fail("该平台找不到游客角色");
        }
        List<Role> roleListByAccountId = roleService.getRoleListByAccountId(accountId);
        if (CollectionUtils.isEmpty(roleListByAccountId)) {
            return ResultJson.fail("该账号不包含角色");
        }
        List<Role> collect = roleListByAccountId.stream()
                .filter(role -> touristRoleByIndustryId.stream()
                        .map(Role::getId)
                        .anyMatch(id -> Objects.equals(role.getId(), id)))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
            return ResultJson.fail("该账号不包含任何一个游客角色");
        }
        //判断是否有项目关联
        ProjectQuery projectQuery = new ProjectQuery();
        projectQuery.setAccountId(accountId);
        Account account = accountService.findById(accountId);
        List<Project> list = projectService.list(projectQuery, account);
        boolean containerProject = false;
        if (!CollectionUtils.isEmpty(list)) {
            containerProject = list.stream().map(project -> project.getId()).collect(Collectors.toList()).contains(projectId);
        }
        if (!containerProject) {
            //为该账号，添加项目关联；添加项目、角色权限组
            List<Integer> projectIds = Collections.singletonList(projectId);
            List<Integer> roleIds = touristRoleByIndustryId.stream().map(role -> role.getId()).collect(Collectors.toList());
            accountService.addProjectToAccount(accountId, roleIds, projectIds);
            return ResultJson.success("新增游客角色成功");
        } else {
            return ResultJson.success("该账号已和项目关联");
        }
    }
}
